package top.huxy.web.util;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;

import javax.activation.MimetypesFileTypeMap;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;

/**
 * @author HuXY
 */
public class FileUtils {
    private FileUtils() {
    }

    /**
     * 获取文件ContentType
     *
     * @param file 文件
     * @return ContentType
     */
    public static String getContentType(File file) {
        URI uri = file.toURI();
        Path path = Paths.get(uri);
        String content_type = null;
        try {
            content_type = Files.probeContentType(path);
        } catch (IOException ignored) {
        }
        //若失败则调用另一个方法进行判断
        if (content_type == null) {
            content_type = new MimetypesFileTypeMap().getContentType(file);
        }
        return content_type;
    }

    /**
     * 获取文件的后缀名
     *
     * @param file 文件
     * @return 后缀名
     */
    public static String getSuffix(File file) {
        String name = file.getName();
        int i = name.lastIndexOf('.');
        if (i != -1) {
            return name.substring(i + 1);
        }
        return "";
    }

    /**
     * dir中是否存在内容相同的file
     */
    public static File getEqualFile(File dir, File file) {
        if (!dir.exists()) {
            throw new IllegalArgumentException("dir 必需存在");
        }
        if (!dir.isDirectory()) {
            throw new IllegalArgumentException("dir 必须时文件夹");
        }
        if (!file.exists()) {
            throw new IllegalArgumentException("file 必需存在");
        }
        if (!file.isFile()) {
            throw new IllegalArgumentException("file 必需是文件");
        }
        long length = file.length();

        File[] files = dir.listFiles(f -> f.length() == length);
        if (files == null || files.length == 0) {
            return null;
        }

        byte[] b1 = FileUtil.readBytes(file);

        for (File f : files) {
            byte[] b2 = FileUtil.readBytes(f);
            if (Arrays.equals(b1, b2)) {
                return f;
            }
        }

        return null;
    }

    /**
     * 保存图片
     * @param dir 目标目录
     * @param image 图片内容
     * @param fmt 后缀名
     * @return 图片名称。无路径
     */
    public static String saveImage(String dir, BufferedImage image, String fmt) {
        try {
            File temp = File.createTempFile(IdUtil.fastSimpleUUID(), ".tmp");
            ImageIO.write(image, fmt, temp);
            File dirFile = new File(dir);

            dirFile.mkdirs();

            long tempFileLength = temp.length();

            File[] files = dirFile.listFiles(file -> file.length() == tempFileLength);
            if (files == null || files.length == 0) {
                //没有相同图片，直接保存
                String newName = IdUtil.fastSimpleUUID() + "." + fmt;
                if (!temp.renameTo(new File(dir + newName))) {
                    System.out.println("rename失败0");
                }

                return newName;
            }

            byte[] b1 = FileUtil.readBytes(temp);
            for (File file : files) {
                byte[] b0 = FileUtil.readBytes(file);
                if (Arrays.equals(b0, b1)) {
                    //删除临时文件
                    temp.delete();
                    return file.getName();
                }
            }

            //没有相同图片，直接保存
            String newName = IdUtil.fastSimpleUUID() + "." + fmt;
            if (temp.renameTo(new File(dir + newName))) {
                System.out.println("rename失败1");
            }
            return newName;
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }
    }

    /**
     *
     * @param dir 目标目录
     * @param data 文件内容
     * @param fmt 后缀名
     * @return 文件名。不带路径
     */
    public static String saveFile(String dir, byte[] data, String fmt) {
        File dirPath = new File(dir);
        dirPath.mkdirs();

        File[] files = dirPath.listFiles(f -> f.length() == data.length && Arrays.equals(data, FileUtil.readBytes(f)));
        if (files == null || files.length == 0) {
            //保存文件
            String name = IdUtil.fastSimpleUUID() + "." + fmt;
            File out = new File(dir + name);
            try (BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(out))) {
                bufferedOutputStream.write(data);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return name;
        } else {
            if (files.length > 1) {
                System.out.println("不在预期的结果,静态资源目录下有多个相同内容的文件");
            }
            return files[0].getName();
        }
    }

    /**
     * 检验arr中的路径是否全是文件
     *
     * @param arr 文件路径
     * @return arr全是文件
     */
    public static boolean allIsFile(String... arr) {
        for (String path : arr) {
            if (!new File(path).isFile()) {
                return false;
            }
        }
        return true;
    }
}